package com.hyperf.spring.boot.autoconfigure;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Zookeeper自动装配
 *
 * @author lizhaoyang
 */
@Configuration
@ConditionalOnClass(CuratorFramework.class)
@ConditionalOnProperty(prefix = "hyperf.zookeeper", name = "address")
@EnableConfigurationProperties(ZookeeperAutoConfiguration.ZookeeperProperties.class)
public class ZookeeperAutoConfiguration {
    /**
     * 如果Zookeeper-URL以Scheme开始，需要移除Scheme
     */
    public static final String SCHEME = "zookeeper://";

    private ZookeeperProperties properties;

    public ZookeeperAutoConfiguration(ZookeeperProperties properties) {
        this.properties = properties;
    }

    @Bean(initMethod = "start", destroyMethod = "close")
    @ConditionalOnMissingBean(CuratorFramework.class)
    public CuratorFramework curatorFramework() {
        String address = this.properties.getAddress();
        if (address.startsWith(SCHEME)) {
            address = address.substring(SCHEME.length());
        }

        RetryPolicy retryPolicy = new ExponentialBackoffRetry(properties.getMaxRetries(), properties.getMaxRetries());
        return CuratorFrameworkFactory
                .builder()
                .connectString(address)
                .sessionTimeoutMs(properties.getSessionTimeout())
                .connectionTimeoutMs(properties.getConnectionTimeout())
                .retryPolicy(retryPolicy)
                .build();
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @ConfigurationProperties(prefix = "hyperf.zookeeper")
    public static class ZookeeperProperties {

        /**
         * 服务器连接地址
         */
        private String address;

        /**
         * 最大重试次数
         */
        private int maxRetries = 3;

        /**
         * 重试间隔时间，单位毫秒
         */
        private int baseSleepTime = 1000;

        /**
         * 会话超时时间，单位毫秒
         */
        private int sessionTimeout = 60000;

        /**
         * 连接创建超时时间，单位毫秒
         */
        private int connectionTimeout = 60000;
    }
}
